package com.element.ui.border;

import javax.swing.border.EtchedBorder;
import java.awt.*;

/**
 * 只在指定边绘制的蚀刻边框
 */
public class PartialEtchedBorder extends EtchedBorder implements PartialSide {
	private int _sides;
	private boolean _roundedCorners = false;

	public PartialEtchedBorder() {
		this(ALL);
	}

	/**
	 * @param sides {@link PartialSide} 中的常量
	 */
	public PartialEtchedBorder(int sides) {
		_sides = sides;
	}

	/**
	 * @param etchType
	 * @param sides    {@link PartialSide} 中的常量
	 */
	public PartialEtchedBorder(int etchType, int sides) {
		super(etchType);
		_sides = sides;
	}

	/**
	 * @param highlight
	 * @param shadow
	 * @param sides     {@link PartialSide} 中的常量
	 */
	public PartialEtchedBorder(Color highlight, Color shadow, int sides) {
		super(highlight, shadow);
		_sides = sides;
	}

	/**
	 * @param etchType
	 * @param highlight
	 * @param shadow
	 * @param sides     {@link PartialSide} 中的常量
	 */
	public PartialEtchedBorder(int etchType, Color highlight, Color shadow, int sides) {
		super(etchType, highlight, shadow);
		_sides = sides;
	}

	public int getSides() {
		return _sides;
	}

	public void setSides(int sides) {
		_sides = sides;
	}

	@Override
	public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
		int w = width;
		int h = height;

		g.translate(x, y);

		if (c.getBackground() == null) {
			c.setBackground(Color.GRAY); // just a workaround to resolve the background is null issue.
		}

		Color shadowColor = getShadowColor(c);
		Color highlightColor = getHighlightColor(c);

		if (_sides == ALL) {
			g.setColor(etchType == LOWERED ? shadowColor : highlightColor);
			if (isRoundedCorners()) {
				g.drawRoundRect(0, 0, w - 2, h - 2, 2, 2);
			} else {
				g.drawRect(0, 0, w - 2, h - 2);
			}

			g.setColor(etchType == LOWERED ? highlightColor : shadowColor);
			g.drawLine(1, h - 3, 1, 1);
			g.drawLine(1, 1, w - 3, 1);

			g.drawLine(0, h - 1, w - 1, h - 1);
			g.drawLine(w - 1, h - 1, w - 1, 0);
		} else {
			if ((_sides & NORTH) != 0) {
				g.setColor(etchType == LOWERED ? shadowColor : highlightColor);
				g.drawLine(0, 0, w - 2, 0);
				g.setColor(etchType == LOWERED ? highlightColor : shadowColor);
				g.drawLine(1, 1, w - 2, 1);
			}
			if ((_sides & SOUTH) != 0) {
				g.setColor(etchType == LOWERED ? shadowColor : highlightColor);
				g.drawLine(0, h - 2, w - 1, h - 2);
				g.setColor(etchType == LOWERED ? highlightColor : shadowColor);
				g.drawLine(0, h - 1, w - 1, h - 1);
			}
			if ((_sides & WEST) != 0) {
				g.setColor(etchType == LOWERED ? shadowColor : highlightColor);
				g.drawLine(0, h - 2, 0, 0);
				g.setColor(etchType == LOWERED ? highlightColor : shadowColor);
				g.drawLine(1, h - 3, 1, 1);
			}
			if ((_sides & EAST) != 0) {
				g.setColor(etchType == LOWERED ? shadowColor : highlightColor);
				g.drawLine(w - 2, h - 2, w - 2, 0);
				g.setColor(etchType == LOWERED ? highlightColor : shadowColor);
				g.drawLine(w - 1, h - 1, w - 1, 0);
			}
		}
		g.translate(-x, -y);
	}

	@Override
	public Insets getBorderInsets(Component c) {
		Insets borderInsets = super.getBorderInsets(c);
		if ((_sides & NORTH) == 0) {
			borderInsets.top = 0;
		}
		if ((_sides & SOUTH) == 0) {
			borderInsets.bottom = 0;
		}
		if ((_sides & WEST) == 0) {
			borderInsets.left = 0;
		}
		if ((_sides & EAST) == 0) {
			borderInsets.right = 0;
		}
		return borderInsets;
	}

	@Override
	public Insets getBorderInsets(Component c, Insets insets) {
		Insets borderInsets = super.getBorderInsets(c, insets);
		if ((_sides & NORTH) == 0) {
			borderInsets.top = 0;
		}
		if ((_sides & SOUTH) == 0) {
			borderInsets.bottom = 0;
		}
		if ((_sides & WEST) == 0) {
			borderInsets.left = 0;
		}
		if ((_sides & EAST) == 0) {
			borderInsets.right = 0;
		}
		return borderInsets;
	}

	/**
	 * Gets the flag indicating if the corner should be painted rounded.
	 *
	 * @return true if the corner should be painted rounded. Otherwise false.
	 * @since 3.4.5
	 */
	public boolean isRoundedCorners() {
		return _roundedCorners;
	}

	/**
	 * Sets the flag indicating if the corner should be painted rounded.
	 * <p/>
	 * By default, the value is false to keep the default behavior backward compatibility.
	 * <p/>
	 * This flag take effects only if the side is {@link #ALL}
	 *
	 * @param roundedCorners the flag
	 * @since 3.4.5
	 */
	public void setRoundedCorners(boolean roundedCorners) {
		_roundedCorners = roundedCorners;
	}
}
